package com.domus.dreamMenu.servidor.bancodados;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Iterator;

import com.domus.dreamMenu.tipos.EntradaConta;
import com.domus.dreamMenu.tipos.EntradaPedido;
import com.domus.dreamMenu.tipos.Pedido;
import com.domus.dreamMenu.tipos.PedidoCozinha;
import com.domus.dreamMenu.tipos.RelacaoConta;

public class ConexaoBancoDadosPedido extends ConexaoBancoDados {
	
	public void inserirPedido(Pedido novo){
		try{
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("BEGIN;");
			comando.execute();
			
			comando = ConexaoBancoDados.conexao.prepareStatement("INSERT INTO pedido " + 
					"VALUES (NEXTVAL('pedido_codigo_pedido_seq'), current_timestamp, ?, ?, ?)"); 
			comando.setInt(1, novo.getConta());
			comando.setInt(2, novo.getMatriculaGarcom());
			comando.setString(3, novo.getObservacoes());
			
			comando.executeUpdate();
			
			Iterator<EntradaPedido> iterator = novo.getEntradas();
			EntradaPedido entrada;
			comando = ConexaoBancoDados.conexao.prepareStatement("INSERT INTO pedido_prato VALUES " +
					"(CURRVAL('pedido_codigo_pedido_seq'),?, ?)");
			while(iterator.hasNext()){
				entrada = iterator.next();
				comando.setInt(1, entrada.getCodigoPrato());
				comando.setInt(2, entrada.getQuantidade());
				
				comando.executeUpdate();
			}
			
			comando = ConexaoBancoDados.conexao.prepareStatement("END;");
			comando.execute();
			
			ConexaoBancoDados.conexao.commit();
				
		}catch (SQLException e){
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	public void atualizarPedido(int codigo, Pedido novo){
		try {
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("BEGIN;");
			comando.execute();
			
			comando = ConexaoBancoDados.conexao.prepareStatement("UPDATE pedido SET " +
					"matricula_garcom = ?, observacoes = ? WHERE codigo_pedido = ?");
			comando.setInt(1, novo.getMatriculaGarcom());
			comando.setString(2, novo.getObservacoes());
			comando.setInt(3, codigo);
			
			comando.executeUpdate();
			
			comando = ConexaoBancoDados.conexao.prepareStatement("DELETE FROM pedido_prato WHERE " +
					"codigo_pedido = ?");
			comando.setInt(1, codigo);
			
			comando.executeUpdate();
			
			Iterator<EntradaPedido> iterator = novo.getEntradas();
			EntradaPedido entrada;
			comando = ConexaoBancoDados.conexao.prepareStatement("INSERT INTO pedido_prato VALUES " +
					"(?, ?, ?)");
			while(iterator.hasNext()){
				entrada = iterator.next();
				comando.setInt(1, codigo);
				comando.setInt(2, entrada.getCodigoPrato());
				comando.setInt(3, entrada.getQuantidade());
				
				comando.executeUpdate();
			}
			
			comando = ConexaoBancoDados.conexao.prepareStatement("END;");
			comando.execute();
			
			ConexaoBancoDados.conexao.commit();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void removerPedido(int codigo){
		try {
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("DELETE FROM pedido " +
					"WHERE codigo_pedido = ?");
			comando.setInt(1, codigo);
			
			comando.executeUpdate();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public RelacaoConta getPedidos(int conta) {
		try {
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("SELECT codigo_pedido " +
					"FROM pedido WHERE codigo_conta = ?");
			comando.setInt(1, conta);
			
			ResultSet resultSetConta = comando.executeQuery();
			ArrayList<EntradaConta> entradas = new ArrayList<EntradaConta>(); 
			
			while(resultSetConta.next()){
				int codigoPedido = resultSetConta.getInt(1);
				
				comando = ConexaoBancoDados.conexao.prepareStatement("SELECT nome, quantidade, preco " +
						"FROM pedido_prato pp, prato p WHERE pp.codigo_pedido = ? AND pp.codigo_prato = " +
						"p.codigo");
				comando.setInt(1, codigoPedido);
				
				ResultSet resultSetPedido = comando.executeQuery();
				
				while(resultSetPedido.next()){
					String nomePrato = resultSetPedido.getString(1);
					int quantidade = resultSetPedido.getInt(2);
					float preco = resultSetPedido.getFloat(3);
					
					entradas.add(new EntradaConta(nomePrato, quantidade, preco));
				}
			}
			
			return new RelacaoConta(entradas, conta);
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}

	private void criarConta(int mesa) {
		try {
			System.out.print(mesa);
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("INSERT INTO conta " +
					"VALUES (NEXTVAL('conta_codigo_seq'), current_timestamp, NULL, ?)");
			comando.setInt(1, mesa);
			
			comando.executeUpdate();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public RelacaoConta fecharConta(int mesa) {
		try {
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("BEGIN;");
			comando.execute();
			
			comando = ConexaoBancoDados.conexao.prepareStatement("SELECT codigo FROM conta WHERE " +
					"fechamento IS NULL AND numero_mesa = ?");
			comando.setInt(1, mesa);
			ResultSet resultSetConta = comando.executeQuery();
			
			resultSetConta.next();
			int conta = resultSetConta.getInt(1);
			System.out.println("fechar conta: "+conta);
			RelacaoConta relacao = this.getPedidos(conta);
			
			comando = ConexaoBancoDados.conexao.prepareStatement("UPDATE conta SET fechamento = " +
					"current_timestamp WHERE fechamento IS NULL AND numero_mesa = ?");
			comando.setInt(1, mesa);			
			comando.executeUpdate();
			
			comando = ConexaoBancoDados.conexao.prepareStatement("END");
			comando.execute();
			
			return relacao;
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}

	public void atualizarConta(int mesaAtual, int novaMesa) {
		try {
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("UPDATE conta SET " +
					"numero_mesa = ? WHERE fechamento IS NULL AND numero_mesa = ?");
			comando.setInt(1, novaMesa);
			comando.setInt(2, mesaAtual);
			
			comando.executeUpdate();
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public int getNumeroConta(int mesa) {
		try {
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("SELECT codigo " +
					"FROM conta WHERE numero_mesa = ? AND fechamento IS NULL");
			comando.setInt(1, mesa);			
			ResultSet resultSetCodigoConta = comando.executeQuery();
			
			if(resultSetCodigoConta.next())
				return resultSetCodigoConta.getInt(1);
			else { // abrir conta
				this.criarConta(mesa);
				
				comando = ConexaoBancoDados.conexao.prepareStatement(
						"SELECT currval('conta_codigo_seq')");
				resultSetCodigoConta = comando.executeQuery();
				resultSetCodigoConta.next();
				
				return resultSetCodigoConta.getInt(1);
			}
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return -1;
	}

	public PedidoCozinha getPedidoCozinha() {
		try {
			PreparedStatement comando = ConexaoBancoDados.conexao.prepareStatement("SELECT c.numero_mesa, " +
					"p.observacoes, p.codigo_pedido FROM pedido p, conta c WHERE p.codigo_conta = c.codigo " +
					"AND p.codigo_pedido = (SELECT MAX(codigo_pedido) FROM pedido)");
			
			ResultSet resultSet = comando.executeQuery();
			
			resultSet.next();
			
			int mesa = resultSet.getInt(1);
			String observacoes = resultSet.getString(2);
			
			comando = ConexaoBancoDados.conexao.prepareStatement("SELECT nome FROM prato p, pedido_prato pp " +
					"WHERE pp.codigo_prato = p.codigo AND " +
					"pp.codigo_pedido = (SELECT MAX(codigo_pedido) FROM pedido)");
			ResultSet resultSetPrato = comando.executeQuery();
			ArrayList<String> nomesPratos = new ArrayList<String>();
						
			while(resultSetPrato.next()){
				String nomePrato = resultSetPrato.getString(1);
				
				nomesPratos.add(nomePrato);
			}
			
			return new PedidoCozinha(nomesPratos, observacoes, mesa);
						
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return null;
	}

}
